/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.adaptor;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.field.FieldGenerator;
import com.inspur.edp.caf.generator.item.ClassGeneratorContext;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.cef.api.RefObject;
import com.inspur.edp.cef.api.manager.IRepositoryFactory;
import com.inspur.edp.cef.api.repository.IRootRepository;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.entity.condition.FilterCondition;
import com.inspur.edp.cef.entity.condition.SortCondition;
import com.inspur.edp.cef.entity.dependenceTemp.DataValidator;
import com.inspur.edp.cef.gencommon.ReflectionUtils;
import com.inspur.edp.cef.generator.coreGenerator.base.accessorgen.property.NodeCodeGenerator;
import com.inspur.edp.cef.generator.overall.GeneratorUtil;
import com.inspur.edp.cef.generator.repository.CefRepoAssembler;
import com.inspur.edp.cef.generator.repository.RepositoryGenUtil;
import com.inspur.edp.cef.generator.repository.adaptor.adaptoritem.IsChildAdaptorVarGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.AdaptorConstructorGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.DefaultFilterGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.DefaultSortMethodGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.GetLogicDeleteInfoGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.createinstance.EntityCreateInsGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.method.readproperty.DataTypeReadPropertyGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.property.DboIDPropertyGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.property.IsChildAdaptorPropGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.property.PrimaryPropGenerator;
import com.inspur.edp.cef.generator.repository.adaptor.property.VersionControlPropGenerator;
import com.inspur.edp.cef.generator.repository.dac.DataTypeDacGenContext;
import com.inspur.edp.cef.repository.adaptoritem.EntityRelationalReposAdaptor;
import com.inspur.edp.cef.repository.assembler.AssociationInfo;
import com.inspur.edp.cef.repository.assembler.DataTypeAssembler;
import com.inspur.edp.cef.repository.assembler.entity.ColumnInfo;
import com.inspur.edp.cef.repository.assembler.entity.DbTableInfo;
import com.inspur.edp.cef.repository.assembler.entity.ExtendEntityAssembler;
import com.inspur.edp.cef.repository.dbcolumninfo.DbColumnInfo;
import com.inspur.edp.cef.repository.dbcolumninfo.DbColumnInfoCollection;
import com.inspur.edp.cef.repository.utils.TenantUtil;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.lcm.databaseobject.api.DatabaseObjectServiceForWebIde;
import io.iec.edp.caf.databaseobject.api.entity.DatabaseObjectColumn;
import io.iec.edp.caf.databaseobject.api.entity.DatabaseObjectTableCore;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Map;
import javax.xml.soap.Node;
import org.eclipse.jdt.core.dom.Modifier;
import org.springframework.util.StringUtils;

public abstract class EntityRelationReposAdaptorGenerator extends EntityAdaptorGenerator {

	///#region 字段与属性
//	private MainEntityAssembler mainAssembler;
	private DatabaseObjectTableCore dbo;
	private String primaryColumnName;
	private String parentIdColumnName;
	private String queryTableName;
	private String queryColumns;
	private String insertColumns;
	private String insertParams;
	private ArrayList<FilterCondition> filterConditions;
	private ArrayList<SortCondition> sortConditions;
	private java.util.HashMap<String, String> mappingPropNames = new java.util.HashMap<String, String>();
	private DataTypeDacGenContext dacContext;
	private CefRepoAssembler mainAssembler;
	public String getGeneratedName() {
		return getName();
	}

	// endregion
	public EntityRelationReposAdaptorGenerator(IGspCommonObject gspCommonObject, DataTypeDacGenContext dacContext, String nodeCode, boolean isChild) {
		super(gspCommonObject, dacContext, nodeCode, isChild);
		this.dacContext = dacContext;
		mainAssembler = new CefRepoAssembler(gspCommonObject, dacContext.getReposContext().getCefContext());
		init();
	}

	// region init
	private void init() {
		initTableInfo();
		initColumns();
//		initAssociationInfo();
		//getQueryTableName();
		//BuildQueryColumns();
		initConditions();
	}
//
//	@Autowired
//	private IDatabaseObjectRtService dboservice;

	// region initTable
	private void initTableInfo() {
		String dboId = mainAssembler.getTableInfo().getDboId();

//		String path = DacContext.getReposContext().getCefContext().getCompileContext().getProjPath();
		String path = DacContext.getReposContext().getCefContext().getCefGenContext().getMetadataPath();
		DatabaseObjectServiceForWebIde  dboservice = RepositoryGenUtil.getBeanByType(DatabaseObjectServiceForWebIde.class);
		Object tempVar = dboservice.getDatabaseObjectById(path, dboId);
		dbo = (DatabaseObjectTableCore) ((tempVar instanceof DatabaseObjectTableCore) ? tempVar : null);
		if (dbo == null) {
			throw new RuntimeException("be[" + GeneratorUtil.getName(DacContext.getReposContext().getCefContext().getConfig().getID()) + "]编译时找不到节点[" + NodeCode + "]对应的DBO，ID是" + dboId + "的DBO");
		}
		//DataValidator.checkForNullReference(dbo, "dbo");
		mainAssembler.getTableInfo().setTableName(dbo.getCode());
		//不需要了
		//mainAssembler.getTableInfo().setIsFiscal(dbo.isFiscalTable());
	}
	//endregion

	//region initColumn
	private void initColumns() {
		DbColumns = new DbColumnInfoCollection();

		for (ColumnInfo columnInfo : mainAssembler.getContainColumns()) {
			DbColumnInfo dbColumnInfo = transDbColumnInfo(columnInfo);
			if (dbColumnInfo.getIsPrimaryKey()) {
				primaryColumnName = dbColumnInfo.getDbColumnName();
			}
			if (dbColumnInfo.getIsParentId()) {
				parentIdColumnName = dbColumnInfo.getDbColumnName();
			}
			DbColumns.add(dbColumnInfo);
		}
		//ContainColumns.AddRange(AssemblerItem.ContainColumns);
//		if (ExtendAssemblers == null || ExtendAssemblers.size() < 1) {
//			return;
//		}
//		for (AssemblerInfo extendAssmeblerItem : ExtendAssemblers) {
//			//ContainColumns.AddRange(extendAssmeblerItem.AssemblerInstance);
//			initExtendColumns(extendAssmeblerItem.getAssemblerInstance());
//		}
	}

	private void initExtendColumns(DataTypeAssembler assemblerInstance) {
		ExtendEntityAssembler extendAssembly = (ExtendEntityAssembler) ((assemblerInstance instanceof ExtendEntityAssembler) ? assemblerInstance : null);
		for (ColumnInfo columnInfo : extendAssembly.getContainColumns()) {
			DbColumnInfo dbColumnInfo = transDbColumnInfo(columnInfo);
			DbColumns.add(dbColumnInfo);
		}
	}

	private DbColumnInfo transDbColumnInfo(ColumnInfo columnInfo) {
		DataValidator.checkForNullReference(columnInfo, "columnInfo");
		DatabaseObjectColumn dboColumn = dbo.getColumnById(columnInfo.getDboColumnId());
		if (dboColumn == null) {
			throw new RuntimeException("dbo[" + dbo.getCode() + "]上不存在ID为{columnInfo.DboColumnId}, 名称为{columnInfo.ColumnName}的列");
		}
		DbColumnInfo tempVar = new DbColumnInfo();
		tempVar.setColumnName(columnInfo.getColumnName());
		tempVar.setDbColumnName(dboColumn.getCode());
		tempVar.setLength(dboColumn.getLength());
		tempVar.setPrecision(dboColumn.getPrecision());
		tempVar.setDefaultValue(dboColumn.getDefaultValue());
		tempVar.setColumnType(GeneratorUtil.transDataType(dboColumn.getDataType()));
		tempVar.setIsAssociateRefElement(columnInfo.getIsAssociateRefElement());
		tempVar.setIsMultiLang(columnInfo.getIsMultiLang());
		tempVar.setIsParentId(columnInfo.getIsParentId());
		tempVar.setIsPrimaryKey(columnInfo.getIsPrimaryKey());
		tempVar.setIsUdtElement(columnInfo.getIsUdtElement());
		tempVar.setIsAssociation(columnInfo.getIsAssociation());
		tempVar.setIsEnum(columnInfo.getIsEnum());
		tempVar.setBelongElementLabel(columnInfo.getBelongElementLabel());
		tempVar.setTypeTransProcesser(columnInfo.getTypeTransProcesser());
		DbColumnInfo column = tempVar;
		return column;
	}
	//endregion

	//region initAssociation
//	private void initAssociationInfo() {
//		ArrayList<AssociationInfo> associtateList = mainAssembler.getAssociationInfos();
//		if (associtateList != null && associtateList.size() > 0) {
//			associationInfos.addAll(associtateList);
//		}
////		if (ExtendAssemblers == null || ExtendAssemblers.size() < 1) {
////			return;
////		}
//
////		for (AssemblerInfo extendAssmeblerItem : ExtendAssemblers) {
////
////			ArrayList<AssociationInfo> extendAssocitateList = ((ExtendEntityAssembler) ((extendAssmeblerItem.getAssemblerInstance() instanceof ExtendEntityAssembler) ? extendAssmeblerItem.getAssemblerInstance() : null)).getAssociationInfos();
////			if (extendAssocitateList != null && extendAssocitateList.size() > 0) {
////				associationInfos.addAll(extendAssocitateList);
////			}
////		}
//	}

//	public final String getQueryTableName() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//		//跟之前一致，并且在当前实例上做缓存。
//		queryTableName = getTableNamesWithAssociationInfo(associationInfos, null);
//		return queryTableName;
//	}

	private String getTableNamesWithAssociationInfo(ArrayList<AssociationInfo> associations, ArrayList<String> tableAlias) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
		if (tableAlias == null) {
			tableAlias = new ArrayList<String>();
			mainAssembler.initTableAlias(tableAlias);
		} else {
			mainAssembler.getTableInfo().setAlias(getTableAlias4Association(tableAlias));
		}

		if (associations.size() < 1) {
			tableAlias.add(getAlias());
			return getTableName();
		}
		StringBuilder queryTableNames = new StringBuilder().append(getTableName());

		for (AssociationInfo associationInfo : associations) {
			java.util.HashMap<String, String> associationColumns = new java.util.HashMap<String, String>();
			for (Map.Entry<String, String> item : associationInfo.getRefColumns().entrySet()) {
				associationColumns.put(item.getValue(), "");
			}
			String targetDbColumnName = "";
			//TODO 年度
			//associationInfo.RefRepository.initContext(context.ReposContext.EnvVars);
			Class reposFactoryType = DacContext.getReposContext().getCefContext().entityRepositoryFactory();
			Object tempVar = ReflectionUtils.createInstance(reposFactoryType);
//			reposFactoryType.Assembly.CreateInstance(reposFactoryType.FullName);
			IRepositoryFactory repositoryFactory = (IRepositoryFactory) ((tempVar instanceof IRepositoryFactory) ? tempVar : null);
			IRootRepository refRepository = repositoryFactory.createRepository(associationInfo.getConfigId());
			RefObject<String> tempRef_targetDbColumnName = new RefObject<String>(targetDbColumnName);
			String tableName = refRepository.getTableNameByColumns(associationInfo.getNodeCode(), associationColumns, associationInfo.getTargetColumn(), tempRef_targetDbColumnName, tableAlias);
			targetDbColumnName = tempRef_targetDbColumnName.argvalue;

			initAssociateColumnInfo(associationInfo, associationColumns);

//			String joinTableName = getSqlGenerator().getJoinTableName();
//
//			String sourceColumnName = trans2DbColumn(associationInfo.getSourceColumn());
//			queryTableNames.append(String.format(joinTableName, tableName, sourceColumnName, targetDbColumnName));
		}

		return queryTableNames.toString();
	}

	private String getTableAlias4Association(ArrayList<String> tableAlias) {
		String alias = getAlias();
		if (!tableAlias.contains(alias)) {
			tableAlias.add(alias);
			return alias;
		}

		int index = 1;
		while (true) {
			if (tableAlias.contains(alias + index)) {
				index++;
			} else {
				tableAlias.add(alias + index);
				return alias + index;
			}
		}
	}

	public final String getAlias() {
		return mainAssembler.getTableInfo().getAlias();
	}

	public final String trans2DbColumn(String filedName) {
		//跟原来一致
		if (!DbColumns.contains(filedName)) {
			throw new RuntimeException("未找到字段" + filedName + "，请确认字段名称是否输入正确，或关联引用字段是否已经获取");
		}
		//return assColumns.ContainsKey(filedName) ? assColumns[filedName] : throw new Exception("Error");
		if (DbColumns.getItem(filedName).getIsAssociateRefElement()) {
			return getAssociateDbColumnName(DbColumns.getItem(filedName));
		}
		//return assColumns.ContainsKey(filedName) ? assColumns[filedName] : throw new Exception("Error");

		String dbName = getAlias() + "." + DbColumns.getItem(filedName).getDbColumnName();
		if (DbColumns.getItem(filedName).getIsMultiLang()) {
			dbName = getMultiLangColumnName(dbName);
		}
		return dbName;
	}

	private String getAssociateDbColumnName(DbColumnInfo columnInfo) {
		if (columnInfo.getDbColumnName().equals( "") || columnInfo.getDbColumnName() == null) {
			throw new RuntimeException("尚未获取关联引用字段数据库列名称，请先获取引用字段");
		}
		return columnInfo.getDbColumnName();
	}

	/**
	 * 获取多语列
	 *
	 * @param columnName 列名（DBName）
	 * @return
	 */
	protected String getMultiLangColumnName(String columnName) {
		//string currentLanguage = I18NUtils.getCurrentLanguage();
		//return columnName + I18NUtils.getFieldSuffix(currentLanguage);
		return columnName + "@Language@";
	}

	private void initAssociateColumnInfo(AssociationInfo associationInfo, java.util.HashMap<String, String> associationColumns) {
		for (Map.Entry<String, String> refColumnItem : associationInfo.getRefColumns().entrySet()) {
			if (DbColumns.contains(refColumnItem.getKey())) {
				DbColumns.getItem(refColumnItem.getKey()).setDbColumnName(associationColumns.get(refColumnItem.getValue()));
			} else {
				DbColumnInfo tempVar = new DbColumnInfo();
				tempVar.setColumnName(refColumnItem.getKey());
				tempVar.setDbColumnName(associationColumns.get(refColumnItem.getValue()));
				tempVar.setIsAssociateRefElement(true);
				tempVar.setBelongElementLabel(associationInfo.getSourceColumn());
				DbColumnInfo columnInfo = tempVar;
				DbColumns.add(columnInfo);
			}
		}
	}

	/**
	 * 获取表名（带别名）
	 *
	 * @return
	 */
	public final String getTableName() {
		//var year = Convert.ToString(context.ReposContext.EnvVars["Fiscal"]);
		DbTableInfo tableInfo = mainAssembler.getTableInfo();
		return getTableNameWithYear(tableInfo) + " " + tableInfo.getAlias();
	}

	public final String getTableNameWithYear(DbTableInfo tableInfo) {
		if (tableInfo.getIsFiscal()) {
			return tableInfo.getTableName() + "@YY@";
		}
		return tableInfo.getTableName();
	}

//	public final String getTableNameByColumns(java.util.HashMap<String, String> columns, String keyColumnName, RefObject<String> keyDbColumnName, ArrayList<String> tableAlias) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//		//跟之前一致。
//		ArrayList<AssociationInfo> associations = getAssociationInfos(columns);
//		String tableName = getTableNamesWithAssociationInfo(associations, tableAlias);
//
//		keyDbColumnName.argvalue = trans2DbColumn(keyColumnName);
//
//		List<String> keys = new ArrayList<>();
//		for (String key : columns.keySet()) {
//			keys.add(key);
//		}
//
//		for (int i = 0; i < keys.size(); i++) {
//			columns.put(keys.get(i), trans2DbColumn(keys.get(i)));
//		}
//		return tableName;
//	}

//	private ArrayList<AssociationInfo> getAssociationInfos(java.util.HashMap<String, String> columns) {
//		ArrayList<AssociationInfo> associations = new ArrayList<AssociationInfo>();
//		for (Map.Entry<String, String> columnItem : columns.entrySet()) {
//			if (!DbColumns.contains(columnItem.getKey()) || DbColumns.getItem(columnItem.getKey()).getIsAssociateRefElement()) {
//				associations.add(findInAssociationInfos(columnItem.getKey()));
//			}
//		}
//		return associations;
//	}

//	private AssociationInfo findInAssociationInfos(String columnName) {
//		for (AssociationInfo associationInfo : associationInfos) {
//			if (associationInfo.getRefColumns().containsKey(columnName)) {
//				return associationInfo;
//			}
//		}
//
//		throw new RuntimeException("找不到字段" + columnName);
//	}
	//endregion

	public final void buildQueryColumns() {
		//跟之前一致，并且在当前实例上做缓存。
		StringBuilder columns = new StringBuilder();
		for (DbColumnInfo containColumn : DbColumns) {
			if (columns.toString() != "" && columns.toString() != null) {
				columns.append(",");
			}
			columns.append(trans2DbColumn(containColumn.getColumnName())).append(" AS ").append(containColumn.getColumnName());
		}

		queryColumns = columns.toString();
	}
	//endregion

	//region Impl
	@Override
	protected ClassGeneratorContext createClassInfoContext() {
		return new ClassGeneratorContext();
	}

	protected String getNameSpace() {
		return DacContext.getReposContext().getCefContext().getNameSpace();
	}

	@Override
	protected TypeInfo setParentClass() {
		return new TypeInfo(EntityRelationalReposAdaptor.class);
	}

	@Override
	protected ArrayList<Modifier.ModifierKeyword> getAccessModifier() {
		ArrayList<Modifier.ModifierKeyword> list = new ArrayList<Modifier.ModifierKeyword>();
		list.add(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
		return list;
	}

	@Override
	protected ArrayList<ClassPropertyGenerator> createPropertyGenerators() {
		ArrayList<ClassPropertyGenerator> propGenerators = super.createPropertyGenerators();
		if (propGenerators == null)
			propGenerators = new ArrayList<ClassPropertyGenerator>();

		//protected abstract string TableName { get; }
		//var tableNameGenerator = new TableNamePropGenerator(mainAssembler);
		//propGenerators.Add(tableNameGenerator);
//		TableAliasPropGenerator tableAliasGenerator = new TableAliasPropGenerator();
//		propGenerators.add(tableAliasGenerator);

//		SqlSnippetCachePropGenerator sqlSnippetCachePropGenerator = new SqlSnippetCachePropGenerator();
//		propGenerators.add(sqlSnippetCachePropGenerator);

//		AdaptorSqlCachePropGenerator adaptorSqlCachePropGenerator = new AdaptorSqlCachePropGenerator();
//		propGenerators.add(adaptorSqlCachePropGenerator);

//		BaseAdaptorItemPropGenerator baseAdaptorItemPropGenerator = new BaseAdaptorItemPropGenerator();
//		propGenerators.add(baseAdaptorItemPropGenerator);

		if(IsChildAdaptor) {
			IsChildAdaptorPropGenerator isChildAdaptorPropGenerator = new IsChildAdaptorPropGenerator();
			propGenerators.add(isChildAdaptorPropGenerator);
		}
		//protected abstract string QueryFields { get; }
		//var queryFieldsGenerator = new QueryFieldsPropGenerator(queryColumns);
		//propGenerators.Add(queryFieldsGenerator);
		////protected abstract string QueryTables { get; }
		//var queryTablesGenerator = new QueryTablePropGenerator(queryTableName);
		//propGenerators.Add(queryTablesGenerator);
		//protected abstract string PrimaryKey { get; }
//		PrimaryPropGenerator primaryGenerator = new PrimaryPropGenerator(primaryColumnName);
//		propGenerators.add(primaryGenerator);
		////protected abstract string DefaultSort { get; }
		//var sortConditionStr = BuildOrderByCondition();
		//var sortGenerator = new DefaultSortGenerator(sortConditionStr);
		//propGenerators.Add(sortGenerator);

		//protected abstract string ConfigId { get; }
//		ConfigIdPropGenerator configIdGenerator = new ConfigIdPropGenerator(DacContext.getReposContext().getCefContext().getConfig().getID());
//		propGenerators.add(configIdGenerator);


		//public abstract string ParentJoin { get; }
		String parentIdDbColumn = null;
		if (IsChildAdaptor)
		//Bug 284235, parentIdColumnName已经是dbColumnName了而且不可能是多语字段, 所以不需要走trans2DbColumn
		{
			parentIdDbColumn = getAlias() + "." + parentIdColumnName; //trans2DbColumn(parentIdColumnName);
		}

		propGenerators.add(new DboIDPropertyGenerator(dbo.getId()));

		//protected abstract bool EnableFiscal { get; }
		//var fiscalGen = new EnableFiscalGenerator(dbo.IsFiscalTable);
		//propGenerators.Add(fiscalGen);


		ArrayList<Modifier.ModifierKeyword> modifierKeywords = new ArrayList<>();
		modifierKeywords.add(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
		NodeCodeGenerator nodeCodeGen = new NodeCodeGenerator(mainAssembler.getNodeCode(), modifierKeywords, true);
		propGenerators.add(nodeCodeGen);

		String versionId = ((IGspCommonObject)gspCommonDataType).getBelongModel().getVersionContronInfo().getVersionControlElementId();
		if(!StringUtils.isEmpty(versionId)) {
			String versionPropName = "";
			for(IGspCommonField field:gspCommonDataType.getContainElements()){
				if(versionId.equals(field.getID())){
					versionPropName = field.getLabelID();
					break;
				}
			}
//			VersionControlPropGenerator vcsPropGen =
//					new VersionControlPropGenerator(versionPropName);
//			propGenerators.add(vcsPropGen);
		}
		return propGenerators;
	}

	private String buildOrderByCondition() {
		StringBuilder orderByBuilder = new StringBuilder();
		if (sortConditions != null && sortConditions.size() > 0) {
			for (SortCondition orderByItem : sortConditions) {
				if (orderByBuilder.toString() != null && orderByBuilder.toString() != "") {
					orderByBuilder.append(", ");
				}
				String filedName = trans2DbColumn(orderByItem.getSortField());
				orderByBuilder.append(orderByItem.trans2Sql(filedName));
			}
		}

		return String.valueOf(orderByBuilder);
	}


	private String getInsertColumns()
	{
		buildInsertColumnsAndParams();
		return insertColumns;
	}

	private void buildInsertColumnsAndParams() {
		//跟之前一致，并且在当前实例上做缓存。
		StringBuilder columnNames = new StringBuilder();
		StringBuilder valueParamter = new StringBuilder();
		int paramterNum = 0;
		for (DbColumnInfo columnInfo : DbColumns) {
			if (columnInfo.getIsAssociateRefElement()) {
				continue;
			}
			if (columnNames.toString() != null &&  "".equals(columnNames.toString()) == false) {
				columnNames.append(", ");
				valueParamter.append(", ");
			}
			if (columnInfo.getIsMultiLang()) {
				columnNames.append(getMultiLangColumnName(columnInfo.getDbColumnName()));
			} else {
				columnNames.append(columnInfo.getDbColumnName());
			}
			valueParamter.append("?" + (paramterNum++));
		}

		if (TenantUtil.IsDiscriminator()) {
			String tenantColName = TenantUtil.GetTenantColumnName();
			columnNames.append(", ").append(tenantColName);
			valueParamter.append(", ").append("?" + (paramterNum++));
		}

		insertColumns = columnNames.toString();
		insertParams = valueParamter.toString();
	}
	//endregion

	private String getModifySql() {
		//TODO 后续改到SqlGenerator，或者提到基类
		String modifySql = "Update %1$s Set";
		DbTableInfo tableInfo = mainAssembler.getTableInfo();
		return String.format(modifySql, "@TableName@"); //getTableNameWithYear(tableInfo)
	}

	//endregion

	//region field
	@Override
	protected ArrayList<FieldGenerator> createFieldGenerator() {
		ArrayList<FieldGenerator> filedGenerators = super.createFieldGenerator();
		if (filedGenerators == null) {
			filedGenerators = new ArrayList<FieldGenerator>();
		}
		buildMappingGenerator(filedGenerators);
//		TableAliasFieldGenerator aliasFieldGen = new TableAliasFieldGenerator(mainAssembler);
//		filedGenerators.add(new PropIndexMappingDictVarGenerator());
//		filedGenerators.add(aliasFieldGen);
//		filedGenerators.add(new AdaptorSqlCacheVarGenerator());
//		filedGenerators.add(new SqlSnippetCacheVarGenerator());
//		filedGenerators.add(new BaseAdaptorItemVarGenerator(NodeCode));
		if (IsChildAdaptor)
			filedGenerators.add(new IsChildAdaptorVarGenerator(IsChildAdaptor));
		return filedGenerators;
	}

	//private void initMappingAttributes()
	//{
	//    var properties = BuildPropertyInfos();
	//    foreach (var propertyInfo in properties)
	//    {
	//        var dataTypeAttrType = DacContext.ReposContext.CefContext.DataTypeAttrType;//getDataTypeAttrType();
	//        var dataTypeAttribute = propertyInfo.getCustomAttribute(dataTypeAttrType);
	//        if (dataTypeAttribute == null)
	//            continue;
	//        MappingAttributes.Add(propertyInfo.Name, dataTypeAttribute as NestedConfigAtrribute);
	//    }
	//}

	//region  BuildMappingProp

	private void buildMappingGenerator(ArrayList<FieldGenerator> filedGenerators) {
		for(IGspCommonField gspCommonField: DacContext.getGspCommonDataType().getContainElements()){
			if(!gspCommonField.getIsUdt())
				continue;
//			DataTypeMappingGenerator mppingGen = new DataTypeMappingGenerator(this.dacContext, gspCommonField, gspCommonField.getLabelID());
//			filedGenerators.add(mppingGen);
//			mappingPropNames.put(gspCommonField.getLabelID(), mppingGen.getGeneratedName());
		}
	}
//
//	protected Class getDataTypeAttrType() {
//		return NestedConfigAtrribute.class;
//	}

	//private List<CefPropertyInfo> buildPropertyInfos()
	//{
	//    CefDataInterfaceInfo dataTypeInfo;
	//    if (IsChildAdaptor)
	//        dataTypeInfo = DacContext.ReposContext.CefContext.EntityContext.ChildInterfaceTypes[NodeCode];
	//    else
	//        dataTypeInfo = DacContext.ReposContext.CefContext.EntityContext.MainInterfaceType;
	//    var properties = GeneratorUtil.getProps(dataTypeInfo.BaseInterfate).ToList();

	//    foreach (var extendType in dataTypeInfo.ExtendInterfaces)
	//    {
	//        properties.AddRange(extendType.getProperties().ToList());
	//    }

	//    return properties;
	//}


	//endregion


	//endregion

	@Override
	protected java.util.ArrayList<ClassMethodGenerator> createConstructorGenerators()
	{
		return new java.util.ArrayList<ClassMethodGenerator>(java.util.Arrays.asList(new ClassMethodGenerator[] { new AdaptorConstructorGenerator(getName(),dacContext,
				this.NodeCode) }));
	}

	//region method
	@Override
	protected ArrayList<ClassMethodGenerator> createMethodGenerators() {
		//initMappingAttributes();

		ArrayList<ClassMethodGenerator> methods = null;//super.createMethodGenerators();
		if (methods == null) {
			methods = new ArrayList<ClassMethodGenerator>();
		}
//		if(getReposAssosPropDBMappingGenerator() != null){
//			methods.add(getReposAssosPropDBMappingGenerator());
//		}

		//1 protected abstract List<FilterCondition> getDefaultFilterCondition();
		if(filterConditions !=null && filterConditions.size() > 0){
			DefaultFilterGenerator filterGen = new DefaultFilterGenerator(filterConditions);
			methods.add(filterGen);
		}

		//addGetPropertyValueGenerators(methods);

		//3 protected abstract void initColumns();
//		DacContext.getReposContext().getCefContext().getRootCompileUnitGenCtx().addImport(GspDbDataType.class.getName());
		//4 object getPropertyChangeValue(string key, object value);
//		ChangeValueGenerator changeValueGen = new ChangeValueGenerator(DacContext, gspCommonDataType);
//		methods.add(changeValueGen);
		//protected abstract List<SortCondition> getDefaultSortCondition();
//		DacContext.getReposContext().getCefContext().getRootCompileUnitGenCtx().addImport(SortCondition.class.getName());
		if(sortConditions!=null&&sortConditions.size()!=0) {
			DefaultSortMethodGenerator sortGen = new DefaultSortMethodGenerator(sortConditions);
			methods.add(sortGen);
		}
//		methods.add(new ReposReadPropertyGenerator());
		//TODO GetValue先家在这里，后续看如何调到基类
//		GetValueGenerator getValueGenerator = new GetValueGenerator(DacContext, DbColumns, gspCommonDataType);
//		methods.add(getValueGenerator);
//		methods.add(new GetPropertyColumnMappingMethodGenerator());
//		methods.add(new HasPropColumnMapppingMethodGenerator());
//		methods.add(new SetPropertyColumnMappingMethodGenerator());
		if(((GspBizEntityObject) this.gspCommonDataType).getLogicDeleteControlInfo() != null && ((GspBizEntityObject) gspCommonDataType).getLogicDeleteControlInfo().getEnableLogicDelete()) {
			methods.add(
					new GetLogicDeleteInfoGenerator((GspBizEntityObject) this.gspCommonDataType));
		}
		// protected abstract void initAssociations();

		return methods;
	}

	//private void addGetPropertyValueGenerator(List<ClassMethodGenerator> gens, CefPropertyInfo item)
	//{
	//    var childAttrType = DacContext.ReposContext.CefContext.ChildAttrType;
	//    var childAttribute = item.getCustomAttribute(childAttrType);

	//    var dataTypeAttrType = DacContext.ReposContext.CefContext.DataTypeAttrType;
	//    var dataTypeAttribute = item.getCustomAttribute(dataTypeAttrType);

	//    var extendChildAttrType = DacContext.ReposContext.CefContext.ExtendChildAttribute;
	//    var extendChildAttribute = item.getCustomAttribute(extendChildAttrType);

	//    if (extendChildAttribute != null || childAttribute != null)
	//        return;
	//    if (dataTypeAttribute != null)
	//    {
	//        gens.Add(new CreateUdtDefMethodGenerator(item, DacContext, NodeCode, associationInfos));
	//        return;
	//    }
	//    var propertyName = item.Name;
	//    if (!DbColumns.Contains(propertyName))
	//        return;
	//    var columnInfo = DbColumns[propertyName];
	//    if (columnInfo.IsAssociation)
	//    {
	//        AddAssgetPropValueGenerator(gens, item, columnInfo);
	//        return;
	//    }
	//    else if (columnInfo.IsEnum)
	//    {
	//        AddEnumgetPropValueGenerator(gens, item, columnInfo);
	//        return;
	//    }
	//    else
	//        AddNormalgetPropValueGenerator(gens, item, columnInfo);
	//}

	//private void addAssgetPropValueGenerator(List<ClassMethodGenerator> gens, CefPropertyInfo item, DbColumnInfo columnInfo)
	//{
	//    AssociationInfo associationInfo = getAssociationInfo(item.Name);
	//    gens.Add(new EntityCreateAssocationDefMethodGenerator(associationInfo, item.PropertyType, item.Name));
	//}

	@Override
	public DataTypeReadPropertyGenerator getReadPropertyGenerator() {
		return new DataTypeReadPropertyGenerator(DacContext, gspCommonDataType, this.NodeCode, this.IsChildAdaptor, DbColumns);
	}

	private void initConditions() {
		filterConditions = mainAssembler.getDefaultFilter();
		sortConditions = mainAssembler.GetDefaultSort();
		if (filterConditions == null) {
			filterConditions = new ArrayList<FilterCondition>();
		}
//		if (ExtendAssemblers == null || ExtendAssemblers.size() < 1) {
//			return;
//		}
//
//		for (AssemblerInfo extendAssmeblerItem : ExtendAssemblers) {
//
//			ExtendEntityAssembler extendAssembly = (ExtendEntityAssembler) ((extendAssmeblerItem.getAssemblerInstance() instanceof ExtendEntityAssembler) ? extendAssmeblerItem.getAssemblerInstance() : null);
//			filterConditions.addAll(extendAssembly.getDefaultFilter());
//			sortConditions.addAll(extendAssembly.GetDefaultSort());
//		}

	}

	private EntityCreateInsGenerator getCreateInsGenerator(DataTypeDacGenContext dacContext, String nodeCode, boolean isChild) {
		return new EntityCreateInsGenerator(dacContext, nodeCode, isChild);
	}

	//endregion
}
